package weplay.view.karaoke.lyric
{
	import flash.filters.GlowFilter;
	
	import mx.utils.StringUtil;
	
	import weplay.model.KSCInfo;
	import weplay.model.ModelLocator;

	public class KMCLyricParser implements LyricParser
	{
		
		//**
		
	
		private var kmcList:Array;
		private var kmcRunList:Array = [];
		
		private var _model:ModelLocator;
		
		public function KMCLyricParser()
		{
			_model = ModelLocator.getInstance();
		}
		
		public function parse(data:String):Array
		{
			_model.view.karaokeEditor.videoPlayer.topMaskImg.filters = _model.view.karaokeEditor.videoPlayer.bottomMaskImg.filters = 
				[new GlowFilter(16777215, 1, 4, 4, 8)];
			
			
			var info:String;
			var xml:XML;
			try
			{
				xml = new XML(data);
			}
			catch(e:Error)
			{
				trace(e);
			}
			
			//是否有子节点
			if (! xml.children().length()) {
				trace("没有子节点");
			}
			//分析配置  暂时用不到
//			for each (var xas:XML in xml.attributes()) {
//				var xn:String = xas.name().toString();
//				if (this.hasOwnProperty(xn)) {
//					if (this[xn] is int) {
//						this[xn] = parseInt(xas.toString());
//					} else if (this[xn] is String) {
//						this[xn] = xas.toString();
//					}
//				}
//			}
			
//	<kmc ti="小薇" ar="黄品源" al="情歌精选集" by="晨风" offset="0" duration="3:16">
//		<l t="00:28.556,00:33.752,165,291,2450,163,253,219,315,260,1080">有一个美丽的小女孩</l>
//
			//生成行列表
			kmcList = [];
			for each(var l:XML in xml.children()) {
				var item:KSCInfo = new KSCInfo();
				var timeObj:Object = parseTime(l.@t, 0);
				item.startTimer = timeObj.start;
				item.endTimer = timeObj.end;
				item.lyric = getLineLyric(parseText(l));
				item.singleInfo = timeObj.list;
				kmcList.push( item );
				kmcRunList.push( timeObj.list );
trace(item.startTimer, item.endTimer, item.lyric, item.lyric.length, item.singleInfo);
			}
			return kmcList;
		}
		private var tips:String;
		
		private function getLineLyric(arr:Array):String
		{
			var str:String = "";
			for (var i:int = 0; i < arr.length; i++) 
			{
				str += StringUtil.trim(arr[i]);
			}
			return StringUtil.trim(str);
		}
		
		private function parseText(str:String):Array {
			str = StringUtil.trim(str);
			//解析提示
			var a:Array = str.match(/^\(([^\)]+)\)/);
			if (a is Array) {
				tips = a[0];
				str = str.substr(tips.length);
			}
			//解析行内字段
			var arr:Array = [];
			var reg:RegExp = /^\[([^\]]+)\]/;
			while (str.length) {
				var l:int = 1;
				var s:String;
				var m:Array = str.match(reg);
				if (m is Array) {
					l = m[0].length;
					s = m[1];
				} else {
					s = str.charAt(0);
				}
				arr.push(s);
				str = str.substr(l);
			}
			return arr;
		}
		
		/**
		 *  
		 * @param str
		 * @param offset  偏移量
		 * @return 
		 * 
		 */		
		private function parseTime(str:String, offset:Number):Object {
			var t:Object = {};
			if (str) {
				var arr:Array = array(str);
				t.start = parseMin(arr.shift()) + offset;
				t.end = parseMin(arr.shift()) + offset;
				t.list = arr.map(parseNum);
			}
			return t;
		}
		public static const COLON:RegExp = /\s*\:\s*/;
		public static const COMMA:RegExp = /\s*\,\s*/;
		
		//切割并返回数组
		private function array(input:String):Array {
			input = String(input);
			var arr:Array = input.split(COMMA);
			var out:Array = [];
			for each (var str:String in arr) {
				if (str) {
					out.push(str);
				}
			}
			return out;
		}
		private function parseMin(str:String):Number {
			var arr:Array = str.split(COLON);
			var max:int = arr.length;
			var kms:Number = 0;
			while (arr.length) {
				var v:Number = parseFloat(arr.pop());
				if (! isNaN(v)) {
					kms +=  v * Math.pow(60,max - arr.length - 1);
				}
			}
			kms = int(kms * 1000);
			return kms;
		}
		
		private  function parseNum(element: * ,index:int,arr:Array):Number {
			var v:Number = parseInt(element);
			if (isNaN(v)) {
				v = 0;
			}
			return v;
		}
		
		public function getRunList(list:Array):Array
		{
			return [];
		}
		
		public function getTxtByPosition(now:Number):Object
		{
			var obj:Object;
			for (var i:int=0,j:int=kmcList.length; i<j; i++) 
			{
				// 时间点在开始、结束之间
				if (now > kmcList[i].startTimer && now < kmcList[i].endTimer) 
				{
					obj = {
						currentLyric: kmcList[i].lyric,
						nextLyric: i!=j-1 ? kmcList[i+1].lyric : "",
						bool:i%2!=0
					};
					return obj;
				}
			}
			return null;
		}
		
		public function getLengthByPosition(now:Number):Number
		{
			var len:Number = 0;
			var temp:Array;
			var info:String;
			var lineDuration:Number = 0; // 整行的停留时间
			for (var k:int = 0; k < kmcList.length; k++) 
			{
				// 处于时间点内
				if(now > kmcList[k].startTimer && now < kmcList[k].endTimer)
				{
					temp = kmcRunList[k];
					for (var i:int = 0; i < temp.length; i++) 
					{
						lineDuration += Number(temp[i]);
						if((now - kmcList[k].startTimer) <= lineDuration)
						{
							// 表示现在处于哪一个字
							len += txtWidth*( (now - kmcList[k].startTimer - (lineDuration - Number(temp[i])) )/Number(temp[i]) );
							
							if( Math.abs(len - temp.length*txtWidth)<10 )
							{
								len = temp.length*txtWidth; // seek 不能移动到最宽位置,  hack
							}
							trace(i + "  ~~~~~~~~~~~~~~~!!~:  " + temp.length, kmcList[k].lyric.charAt(i), (now - kmcList[k].startTimer - (lineDuration - Number(temp[i]))), temp[i], 
								(now - kmcList[k].startTimer - (lineDuration - Number(temp[i])) )/Number(temp[i]), "\t" + len  );
							return len; 
						}
						len += txtWidth;
					}
					return len;
				}
				else
				{
					
				}
			}
			return 0;
		}
		
		public function seek(secs:Number):void
		{
		}
		
		private var txtWidth:Number;
		
		public function topSeek(now:Number):void
		{
			txtWidth = _model.view.karaokeEditor.videoPlayer.topTxt.textWidth/_model.view.karaokeEditor.videoPlayer.topTxt.text.length;
			_model.view.karaokeEditor.videoPlayer.topMaskImg.width = getLengthByPosition(now);
			_model.view.karaokeEditor.videoPlayer.bottomMaskImg.width = 0;
		}
		
		public function bottomSeek(now:Number):void
		{
			txtWidth = _model.view.karaokeEditor.videoPlayer.bottomTxt.textWidth/_model.view.karaokeEditor.videoPlayer.bottomTxt.text.length;
			_model.view.karaokeEditor.videoPlayer.bottomMaskImg.width = getLengthByPosition(now);
			trace("bottom: ", _model.view.karaokeEditor.videoPlayer.bottomMaskImg.width, txtWidth);
			_model.view.karaokeEditor.videoPlayer.topMaskImg.width = 0;
			
		}
	}
}